package com.cmes.core;

import com.cmes.core.exception.ResponseCodeException;
import com.cmes.core.utils.ArrayUtils;

/**
 * 返回消息构建
 *
 * @author Bruce.Gong
 * @since 1.0.0-SNAPSHOT
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class ResponseBuilder {

    private static final ResponseCodeData SUCCESS = ok(null);

    /**
     * 响应成功，使用 {@link ResponseData#DEFAULT_SUCCESS_INFO} 进行响应
     *
     * @return ResponseData
     * @see #ok(String, Object)
     */
    public static <T> ResponseCodeData<T> ok() {
        return SUCCESS;
    }

    /**
     * 响应成功，使用 {@link ResponseData#DEFAULT_SUCCESS_INFO} 进行响应
     *
     * @param data 响应数据
     * @return ResponseData
     * @see #ok(String, Object)
     */
    public static <T> ResponseCodeData<T> ok(T data) {
        return ok(null, data);
    }

    /**
     * 响应成功，如果 message 为空，则使用 {@link ResponseData#DEFAULT_SUCCESS_INFO} 进行响应
     *
     * @param info 操作成功提示
     * @param data 业务数据
     * @return ResponseData
     */
    public static <T> ResponseCodeData<T> ok(String info, T data) {
        return new ResponseCodeData<T>().ok(info, data);
    }

    /**
     * 响应失败，使用 {@link ResponseData#DEFAULT_FAIL_INFO} 进行响应
     *
     * @return ResponseData
     * @see #fail(String, String)
     */
    public static <T> ResponseCodeData<T> fail() {
        return fail("", ResponseData.DEFAULT_FAIL_INFO);
    }

    /**
     * 响应失败，如果 message 为空，则使用 {@link ResponseData#DEFAULT_FAIL_INFO} 进行响应
     *
     * @param info 提示语
     * @return ResponseData
     * @see #fail(String, String)
     */
    public static <T> ResponseCodeData<T> fail(String info) {
        return fail(null, info);
    }

    /**
     * 响应失败，如果 message 为空，则使用 {@link ResponseData#DEFAULT_FAIL_INFO} 进行响应
     *
     * @param code 错误码
     * @param info 错误提示语
     * @return ResponseData
     */
    public static <T> ResponseCodeData<T> fail(String code, String info) {
        return new ResponseCodeData<T>().fail(code, info);
    }

    /**
     * 响应失败
     *
     * @param response 错误提示语
     * @return ResponseData
     * @see #fail(String, String)
     */
    public static <T> ResponseCodeData<T> fail(ResponseCodeData<?> response) {
        return fail(response.getCode(), response.getMessage());
    }

    /**
     * 响应失败
     *
     * @param response 错误提示语
     * @param msg      拼接的错误提示语
     * @return ResponseData
     * @see #fail(String, String)
     */
    public static <T> ResponseCodeData<T> failAppendPrev(ResponseCodeData<?> response, String msg) {
        return fail(response.getCode(), msg + response.getMessage());
    }

    /**
     * 响应失败
     *
     * @param response 错误提示语
     * @param msg      拼接的错误提示语
     * @return ResponseData
     * @see #fail(String, String)
     */
    public static <T> ResponseCodeData<T> failAppend(ResponseCodeData<?> response, String msg) {
        return fail(response.getCode(), response.getMessage() + msg);
    }

    /**
     * 响应失败
     *
     * @param errorCode 错误码
     * @return ResponseData
     */
    public static <T> ResponseCodeData<T> fail(ResponseCode errorCode, Object... params) {
        if (ArrayUtils.isEmpty(params)) {
            return fail(errorCode.getCode(), errorCode.getMessage());
        } else {
            return fail(errorCode.getCode(), String.format(errorCode.getMessage(), params));
        }
    }

    /**
     * 响应失败
     *
     * @param exception 异常
     * @return ResponseData
     */
    public static <T> ResponseCodeData<T> fail(ResponseCodeAccessor exception) {
        return fail(exception.getResponseCode());
    }

    /**
     * 响应失败
     *
     * @param exception 异常
     * @return ResponseData
     */
    public static <T> ResponseCodeData<T> fail(ResponseCodeException exception) {
        return fail(exception.getResponseCode(), exception.getMessage());
    }

}
